package fstvis;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.image.BufferedImage;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class PlotPanel extends JPanel
                        implements ItemListener {
	
	double min = 0;
	double max = 0;
	ColourBar cb;

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private ScrollablePicture picture;
	private Field fld;

    public PlotPanel(FstData fstData, ColourBar cb) {
        setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));

        this.fld = fstData.getField();

        this.cb = cb;
        this.min = cb.getMinValue();
        this.max = cb.getMaxValue();
        
        // Get the image to use.
        Image plotimg = (Image)this.generatePlot();
        ImageIcon plot = new ImageIcon(plotimg);

        //Set up the scroll pane.
        picture = new ScrollablePicture(plot, 1); // not sure what this 1 is for
        JScrollPane pictureScrollPane = new JScrollPane(picture);
        pictureScrollPane.setPreferredSize(new Dimension((int)(plot.getIconWidth()*1.01), (int)(plot.getIconHeight()*1.01)));
        pictureScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));

        //Put it in this panel.
        add(pictureScrollPane);
        setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
    }

	@Override
	public void itemStateChanged(ItemEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	
	
   public BufferedImage generatePlot() {
        int ni = 0;
        int nj = 0;
        int[] size = this.fld.getSize();
        ni = size[0];
        nj = size[1];

        int scale = 7;

        if (ni * nj < 1) {
        	System.err.println("Specified field does not exist.");
        	System.exit(1);
        }
        BufferedImage plot = new BufferedImage(ni*scale, nj*scale, BufferedImage.TYPE_INT_RGB);

        //int w = plot.getWidth();
        int h = plot.getHeight();
        
        // Create a graphics context on the buffered image
        Graphics2D g = plot.createGraphics();
        // Draw a white background
        g.setColor(Color.white);
        g.fillRect(0, 0, plot.getWidth(), plot.getHeight());

        double[][] f = fld.getField(); // I suspect this is faster
        double val, x, y;
        Color c;

//        System.out.println ("Min val plotted: " + min);
//        System.out.println ("Max val plotted: " + max);
        
        for (int i=0; i<ni; i++) {
        	for (int j=0; j<nj; j++) {
                val = f[i][j];
                x = i*scale;
                y = j*scale;

                c = cb.getColour(val);
        		g.setColor(c);

//        		if (c != Color.gray && c != Color.DARK_GRAY && c != Color.BLACK)
//        			System.out.println("Drawing box at (" +
//        				x + ", " + y + ") of colour " + c + " for value " + val);
        		
        		// Reverse
				g.fillRect((int)(x), h - (int)(y), scale, scale);
        	}
        }

        return plot;
    }

    public Color chooseColor(double value) {
    	Color c;
    	float val = (float)value;
    	float range = (float)Math.abs(max - min);

    	if (value == 0) {
    		return Color.white;
    	}
    	
    	if (value < min) {
    		return  Color.gray;
    	} else if (value > max) {
    		return Color.DARK_GRAY;
    	}

    	// Normalise the colour
    	val = (val - (float)min)/range;
    	
    	if (value > 0){
    		// Scale in the red
    		c = new Color(val, (float)0.0, (float)0.0);
//System.out.println("[1] Value = " + value + ".  Attempting red = " + ((float)(value/this.max)) + ", c = " + c);
//System.exit(0);
    	} else {
    		// Scale in the blue
    		try {
    			c = new Color(0, (float)0.0, val);
    		} catch (java.lang.IllegalArgumentException ex) {
    			System.err.println("Cannot assing " + val + " as a color.");
    			System.err.println("Min   = " + min);
    			System.err.println("Max   = " + max);
    			System.err.println("Range = " + range);
    			System.err.println("OVal  = " + value);
    			System.err.println("Val   = " + val);
    			System.exit(1);
    			return Color.white;
    		}
//System.out.println("[2] Value = " + value + ".  Attempting red = " + ((float)(value/this.max)) + ", c = " + c);
//System.exit(0);
    	}
    	return c;
    }
}
